home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_300 / 359_11 / patch5.000 / GO32_SYMS.C < prev    next >
C/C++ Source or Header  |  1991-09-11  |  15KB  |  692 lines

  1. /* This is file SYMS.C */
  2. /*
  3. ** Copyright (C) 1991 DJ Delorie, 24 Kirsten Ave, Rochester NH 03867-2954
  4. **
  5. ** This file is distributed under the terms listed in the document
  6. ** "copying.dj", available from DJ Delorie at the address above.
  7. ** A copy of "copying.dj" should accompany this file; if not, a copy
  8. ** should be available from where this file was obtained.  This file
  9. ** may not be distributed without a verbatim copy of "copying.dj".
  10. **
  11. ** This file is distributed WITHOUT ANY WARRANTY; without even the implied
  12. ** warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  13. */
  14.  
  15. /* History:250,1 */
  16. #include <stdio.h>
  17. #include <fcntl.h>
  18. #include <string.h>
  19. #include <stdlib.h>
  20. #include <ctype.h>
  21. #include <io.h>
  22. #include "build.h"
  23. #include "types.h"
  24. #include "syms.h"
  25. #include "tss.h"
  26. #include "stab.h"
  27. #include "aout.h"
  28. #include "utils.h"
  29.  
  30. #if DEBUGGER
  31.  
  32. #define SYMADDR 0xa0000000
  33.  
  34. static word32 sym_brk=SYMADDR;
  35.  
  36. word32 salloc(word32 size)
  37. {
  38.   word32 r = sym_brk;
  39.   size = (size+3)&~3;
  40.   sym_brk +=size;
  41.   return r;
  42. }
  43.  
  44. symsput(word32 where, void *ptr, int size)
  45. {
  46.   memput(where, ptr, size);
  47. }
  48.  
  49. symsget(word32 where, void *ptr, int size)
  50. {
  51.   memget(where, ptr, size);
  52. }
  53.  
  54. typedef struct SYMTREE {
  55.   word32 me;
  56.   word32 nleft, nright, ndown;
  57.   word32 vleft, vright, vdown;
  58.   word32 val;
  59.   word32 type;
  60.   word32 name_len;
  61. } SYMTREE;
  62.  
  63. typedef struct FILENODE {
  64.   word32 me;
  65.   word32 next;
  66.   word32 line_list;
  67.   word32 first_addr, last_addr;
  68.   word32 name_len;
  69. } FILENODE;
  70.  
  71. typedef struct LINENODE {
  72.   word32 me;
  73.   word32 next;
  74.   word32 num;
  75.   word32 addr;
  76. } LINENODE;
  77.  
  78. static word32 symtree_root=0;
  79. static word32 file_list=0;
  80. static word32 nsyms=0;
  81.  
  82. static char tmps[256];
  83. static char tmps2[256];
  84.  
  85. static word32 symtree_add(word32 val, word32 type, char *name)
  86. {
  87.   SYMTREE s, sv, temp;
  88.   int cval;
  89.   int32 cval32;
  90.  
  91.   memset(&temp, 0, sizeof(temp));
  92.   temp.name_len = strlen(name) + 1;
  93.   temp.me = salloc(sizeof(temp)+temp.name_len);
  94.   temp.val = val;
  95.   temp.type = type;
  96.   symsput(temp.me, &temp, sizeof(temp));
  97.   symsput(temp.me+sizeof(temp), name, temp.name_len);
  98.  
  99.   if (symtree_root == 0)
  100.   {
  101.     symtree_root = temp.me;
  102.     return temp.me;
  103.   }
  104.   s.me = symtree_root;
  105.   while (1)
  106.   {
  107.     symsget(s.me, &s, sizeof(s));
  108.     symsget(s.me+sizeof(s), tmps, s.name_len);
  109.     cval = strcmp(name, tmps);
  110.     if ((cval == 0) &&
  111.         ( (s.val == 0)
  112.        || (val == 0)
  113.        || (s.val == val)))
  114.     {
  115.       if (val)
  116.       {
  117.         s.val = val;
  118.         s.type = type;
  119.         symsput(s.me, &s, sizeof(s));
  120.       }
  121.       return temp.me;
  122.     }
  123.     else if (cval == 0)
  124.     {
  125.       if (s.ndown == 0)
  126.       {
  127.         s.ndown = temp.me;
  128.         symsput(s.me, &s, sizeof(s));
  129.         break;
  130.       }
  131.       s.me = s.ndown;
  132.     }
  133.     else if (cval < 0)
  134.     {
  135.       if (s.nleft == 0)
  136.       {
  137.         s.nleft = temp.me;
  138.         symsput(s.me, &s, sizeof(s));
  139.         break;
  140.       }
  141.       s.me = s.nleft;
  142.     }
  143.     else
  144.     {
  145.       if (s.nright == 0)
  146.       {
  147.         s.nright = temp.me;
  148.         symsput(s.me, &s, sizeof(s));
  149.         break;
  150.       }
  151.       s.me = s.nright;
  152.     }
  153.   }
  154.   nsyms++;
  155.  
  156.   sv.me = symtree_root;
  157.   while (1)
  158.   {
  159.     symsget(sv.me, &sv, sizeof(sv));
  160.     if (sv.me == temp.me)
  161.       return temp.me;
  162.     cval32 = val - sv.val;
  163.     if (cval32 == 0)
  164.     {
  165.       if (sv.vdown == 0)
  166.       {
  167.         sv.vdown = temp.me;
  168.         symsput(sv.me, &sv, sizeof(sv));
  169.         break;
  170.       }
  171.       sv.me = sv.vdown;
  172.     }
  173.     else if (cval32 < 0)
  174.     {
  175.       if (sv.vleft == 0)
  176.       {
  177.         sv.vleft = temp.me;
  178.         symsput(sv.me, &sv, sizeof(sv));
  179.         break;
  180.       }
  181.       sv.me = sv.vleft;
  182.     }
  183.     else
  184.     {
  185.       if (sv.vright == 0)
  186.       {
  187.         sv.vright = temp.me;
  188.         symsput(sv.me, &sv, sizeof(sv));
  189.         break;
  190.       }
  191.       sv.me = sv.vright;
  192.     }
  193.   }
  194.   return temp.me;
  195. }
  196.  
  197. static symtree_print(word32 s, int byval, int level)
  198. {
  199.   SYMTREE tmp;
  200.   if (s == 0)
  201.     return;
  202.   symsget(s, &tmp, sizeof(tmp));
  203.   if (byval)
  204.     symtree_print(tmp.vleft, byval, level+1);
  205.   else
  206.     symtree_print(tmp.nleft, byval, level+1);
  207.  
  208.   symsget(tmp.me+sizeof(tmp), tmps, tmp.name_len);
  209.   printf("0x%08lx 0x%08lx %*s%s\n", tmp.val, tmp.type, level, "", tmps);
  210.  
  211.   if (byval)
  212.     symtree_print(tmp.vdown, byval, level);
  213.   else
  214.     symtree_print(tmp.ndown, byval, level);
  215.  
  216.   if (byval)
  217.     symtree_print(tmp.vright, byval, level+1);
  218.   else
  219.     symtree_print(tmp.nright, byval, level+1);
  220. }
  221.  
  222. void syms_list(v)
  223. {
  224.   symtree_print(symtree_root, v, 0);
  225. }
  226.  
  227. typedef struct SYM_ENTRY {
  228.   word32 string_off;
  229.   word8 type;
  230.   word8 other;
  231.   word16 desc;
  232.   word32 val;
  233. } SYM_ENTRY;
  234.  
  235. get_string(FILE *f, word32 where)
  236. {
  237.   char *cp;
  238.   if (where != ftell(f))
  239.     fseek(f, where, 0);
  240.   cp = tmps2;
  241.   do {
  242.     *cp++ = fgetc(f);
  243.   } while (cp[-1]);
  244. }
  245.  
  246. void syms_init(char *fname)
  247. {
  248.   GNU_AOUT header;
  249.   int fd, j, per, oldper=-1;
  250.   word32 nsyms, i;
  251.   FILE *sfd;
  252.   word32 sfd_base;
  253.   SYM_ENTRY sym;
  254.   char *strings, *cp;
  255.   word32 string_size;
  256.   word32 last_dot_o=0;
  257.   FILENODE filen;
  258.   LINENODE linen;
  259.  
  260.   filen.me = 0;
  261.   linen.me = 0;
  262.  
  263.   fd = open(fname, O_RDONLY | O_BINARY);
  264.   sfd = fopen(fname, "rb");
  265.  
  266.   read(fd, &header, sizeof(header));
  267.   if ((header.info & 0xffff) == 0x14c)
  268.   {
  269.     lseek(fd, 0xa8L, 0);
  270.     read(fd, &header, sizeof(header));
  271.     lseek(fd, 0xa8+sizeof(header) + header.tsize + header.dsize, 0);
  272.   }
  273.   else if (((header.info & 0xffff) == 0x10b) ||
  274.      ((header.info & 0xffff) == 0x0107))
  275.   {
  276.     lseek(fd, sizeof(header) + header.tsize + header.dsize
  277.       + header.txrel + header.dtrel, 0);
  278.   }
  279.   else
  280.   {
  281.     nsyms = 0;
  282.     return;
  283.   }
  284.  
  285.   printf("Reading symbols...   0%%");
  286.   fflush(stdout);
  287.  
  288.   nsyms = header.symsize / sizeof(SYM_ENTRY);
  289.  
  290.   fseek(sfd, tell(fd)+header.symsize, 0);
  291.   sfd_base = ftell(sfd);
  292.  
  293.   for (i=0; i<nsyms; i++)
  294.   {
  295.     if (nsyms > 1)
  296.       per = i*100L/(nsyms-1);
  297.     else
  298.       per = 100;
  299.     if (per != oldper)
  300.     {
  301.       printf("\b\b\b\b%3d%%", per);
  302.       fflush(stdout);
  303.       oldper = per;
  304.     }
  305.     read(fd, &sym, sizeof(sym));
  306.     if (sym.string_off)
  307.       get_string(sfd, sfd_base+sym.string_off);
  308.     switch (sym.type)
  309.     {
  310.       case N_TEXT:
  311.       case N_TEXT | N_EXT:
  312.         cp = tmps2;
  313.         cp += strlen(cp) - 2;
  314.         if (strcmp(cp, ".o") == 0)
  315.         {
  316.           last_dot_o = sym.val;
  317.           if (filen.me && (filen.last_addr == 0))
  318.           {
  319.             filen.last_addr = last_dot_o - 1;
  320.             symsput(filen.me, &filen, sizeof(filen));
  321.           }
  322.           break;
  323.         }
  324.         if (strcmp(cp, "d.") == 0) /* as in gcc_compiled. */
  325.           break;
  326.       case N_DATA:
  327.       case N_DATA | N_EXT:
  328.       case N_ABS:
  329.       case N_ABS | N_EXT:
  330.       case N_BSS:
  331.       case N_BSS | N_EXT:
  332.       case N_FN:
  333.       case N_SETV:
  334.       case N_SETV | N_EXT:
  335.       case N_SETA:
  336.       case N_SETA | N_EXT:
  337.       case N_SETT:
  338.       case N_SETT | N_EXT:
  339.       case N_SETD:
  340.       case N_SETD | N_EXT:
  341.       case N_SETB:
  342.       case N_SETB | N_EXT:
  343.       case N_INDR:
  344.       case N_INDR | N_EXT:
  345.         if (sym.string_off)
  346.           symtree_add(sym.val, sym.type, tmps2);
  347.         break;
  348.       case N_SO:
  349.         memset(&filen, 0, sizeof(FILENODE));
  350.         filen.name_len = strlen(tmps2)+1;
  351.         filen.me = salloc(sizeof(FILENODE)+filen.name_len);
  352.         symsput(filen.me+sizeof(filen), tmps2, filen.name_len);
  353.         filen.next = file_list;
  354.         file_list = filen.me;
  355.         filen.first_addr = last_dot_o;
  356.         symsput(filen.me, &filen, sizeof(filen));
  357.         break;
  358.       case N_SLINE:
  359.         memset(&linen, 0, sizeof(linen));
  360.         linen.me = salloc(sizeof(LINENODE));
  361.         linen.next = filen.line_list;
  362.         filen.line_list = linen.me;
  363.         linen.num = sym.desc;
  364.         linen.addr = sym.val;
  365.         symsput(linen.me, &linen, sizeof(linen));
  366.         symsput(filen.me, &filen, sizeof(filen));
  367.         break;
  368.     }
  369.   }
  370.   printf(" %ld s